﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Elsa;
using Elsa.Models;
using Elsa.Persistence;
using Elsa.Services;
using Elsa.Services.Models;
using HengTong.Model.Db.System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Wtm.Interfaces;
using TiaoTaoHelper.Wtm.Models;
using TiaoTaoHelper.Wtm.Workflow;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;
using WalkingTec.Mvvm.Core.Models;
using WorkflowStatus = TiaoTaoHelper.Wtm.Models.WorkflowStatus;

namespace HengTong.ViewModel;

/// <summary>
/// CRUD视图模型基类，提供工作流相关功能
/// </summary>
/// <typeparam name="TModel"></typeparam>
public class CrudVm<TModel> : BaseCRUDVM<TModel> where TModel : TopBasePoco, new()
{
    public bool IsMyApprove { get; set; }

    public List<SysWorkflow> MyApproveList { get; set; }

    public List<PropertyControl> PropertyControls { get; set; }

    protected override void InitVM()
    {
        if (Entity.HasID() && Entity is IWorkflow)
        {
            if (Wtm.LoginUserInfo == null)
            {
            }
            else
            {
                var entityId = Entity.ID.ToString();
                // 查询当前数据的工作流节点
                var list = DC.Set<SysWorkflow>()
                    .AsNoTracking()
                    .Where(x => entityId == x.ModelId)
                    .Where(x => x.TenantCode == Wtm.LoginUserInfo.CurrentTenant)
                    .ToList();
                // 查询当前用户的岗位
                var positionList = DC.Set<SysUserJobPosition>()
                    .AsNoTracking()
                    .Include(e => e.JobPosition)
                    .ThenInclude(e => e.Roles)
                    .Where(e => e.UserId == Guid.Parse(Wtm.LoginUserInfo.UserId))
                    .Select(e => e.JobPosition)
                    .ToList();
                // 过滤出当前用户可以审批的节点
                MyApproveList = list.Where(e =>
                        (e.Type == SysWorkflowType.用户 && e.UserCode == Wtm.LoginUserInfo.ITCode) ||
                        (e.Type == SysWorkflowType.角色 && Wtm.LoginUserInfo.Roles.Any(x => x.ID == e.RoleId)) ||
                        (e.Type == SysWorkflowType.部门 && Wtm.LoginUserInfo.Groups.Any(x => x.ID == e.GroupId)) ||
                        (e.Type == SysWorkflowType.岗位 && positionList.Any(x =>
                            x.GroupId == e.GroupId && x.Roles.Any(r => r.RoleId == e.RoleId))))
                    .ToList();
                // 判断是否拥有审批权限
                IsMyApprove = MyApproveList?.Count > 0;
                var store = Wtm.ServiceProvider.GetRequiredService<IWorkflowDefinitionStore>();
                if (MyApproveList != null)
                {
                    foreach (var workflow in MyApproveList)
                    {
                        var definitionId = DC.Set<Elsa_WorkflowDefinition>()
                            .Where(x => x.Name == workflow.WorkflowName)
                            .Select(e => e.DefinitionId)
                            .FirstOrDefault();
                        if (definitionId != null)
                        {
                            var definition = store.FindByDefinitionIdAsync(definitionId, VersionOptions.Published)
                                .Result;
                            if (definition != null)
                            {
                                var activity =
                                    definition.Activities.FirstOrDefault(e => e.ActivityId == workflow.ActivityId);
                                if (activity != null)
                                {
                                    var options = new JsonSerializerOptions
                                    {
                                        PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                                    };
                                    if (activity.Type == nameof(XenHierarchicalApproveActivity))
                                    {
                                        // 如果是目标岗位审批，则显示目标岗位的可编辑属性，否则显示流程发起时的可编辑属性
                                        var targetGroup = activity.Properties.FirstOrDefault(e =>
                                            e.Name == nameof(XenHierarchicalApproveActivity.TargetGroup));
                                        var approveRoles = activity.Properties.FirstOrDefault(e =>
                                            e.Name == nameof(XenHierarchicalApproveActivity.ApproveRoles));
                                        if (targetGroup != null && approveRoles != null)
                                        {
                                            var group = targetGroup.Expressions.FirstOrDefault(e => e.Key == "Literal");
                                            var roles = approveRoles.Expressions.FirstOrDefault(e => e.Key == "Json");
                                            if (!string.IsNullOrWhiteSpace(group.Value) &&
                                                !string.IsNullOrWhiteSpace(roles.Value))
                                            {
                                                var groupId = Guid.Parse(group.Value);
                                                var roleIds = JsonSerializer.Deserialize<List<Guid?>>(roles.Value);
                                                if (positionList.Any(e =>
                                                        e.GroupId == groupId &&
                                                        e.Roles.Any(r => roleIds.Contains(r.RoleId))))
                                                {
                                                    var propertyControls = activity.Properties.FirstOrDefault(e =>
                                                        e.Name == nameof(XenHierarchicalApproveActivity
                                                            .TargetPropertyControls));
                                                    if (propertyControls != null)
                                                    {
                                                        var value = propertyControls.GetExpression("Literal");
                                                        if (!string.IsNullOrWhiteSpace(value))
                                                        {
                                                            PropertyControls =
                                                                JsonSerializer.Deserialize<List<PropertyControl>>(value,
                                                                    options);
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    var propertyControls = activity.Properties.FirstOrDefault(e =>
                                                        e.Name == nameof(XenHierarchicalApproveActivity
                                                            .ProcessPropertyControls));
                                                    if (propertyControls != null)
                                                    {
                                                        var value = propertyControls.GetExpression("Literal");
                                                        if (!string.IsNullOrWhiteSpace(value))
                                                        {
                                                            PropertyControls =
                                                                JsonSerializer.Deserialize<List<PropertyControl>>(value,
                                                                    options);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    if (activity.Type == nameof(XenApproveActivity))
                                    {
                                        var propertyControls = activity.Properties.FirstOrDefault(e =>
                                            e.Name == nameof(XenApproveActivity.PropertyControls));
                                        if (propertyControls != null)
                                        {
                                            var value = propertyControls.GetExpression("Literal");
                                            if (!string.IsNullOrWhiteSpace(value))
                                            {
                                                PropertyControls =
                                                    JsonSerializer.Deserialize<List<PropertyControl>>(value, options);
                                            }
                                        }
                                    }

                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        base.InitVM();
    }


    /// <summary>
    /// 启动工作流
    /// </summary>
    /// <param name="flowName"></param>
    /// <returns></returns>
    public override async Task<RunWorkflowResult> StartWorkflowAsync(string flowName = null)
    {
        if (!typeof(IWorkflow).IsAssignableFrom(typeof(TModel)))
        {
            MSD.AddModelError(" ", CoreProgram._localizer?["Sys.NoWorkflow"]);
            return null;
        }

        if (!Entity.HasID())
        {
            return null;
        }

        if (Wtm.LoginUserInfo == null || Wtm.LoginUserInfo.Groups.Count == 0 || Entity is IBill { GroupId: null })
        {
            MSD.AddModelError(" ", "用户没有分配部门，无法启动工作流");
            return null;
        }

        string workflowDefinitionId;
        string workflowName;
        if (string.IsNullOrEmpty(flowName))
        {
            var temp = DC.Set<Elsa_WorkflowDefinition>()
                .Where(x => x.Data.Contains(
                    $"\"contextType\": \"{typeof(TModel).FullName}, {typeof(TModel).Assembly.GetName().Name}\""))
                .Select(x => new { id = x.DefinitionId, name = x.Name })
                .FirstOrDefault();
            workflowDefinitionId = temp?.id;
            workflowName = temp?.name;
        }
        else
        {
            var temp = DC.Set<Elsa_WorkflowDefinition>()
                .Where(x => x.Name == flowName)
                .Select(x => new { id = x.DefinitionId, name = x.Name })
                .FirstOrDefault();
            workflowDefinitionId = temp?.id;
            workflowName = temp?.name;
        }

        if (string.IsNullOrWhiteSpace(workflowDefinitionId))
        {
            MSD.AddModelError(" ", CoreProgram._localizer?["Sys.NoWorkflow"]);
            return null;
        }

        var any = DC.Set<SysWorkflow>()
            .Any(e => e.WorkflowName == workflowName && e.ModelId == Entity.GetID().ToString());
        if (any)
        {
            MSD.AddModelError(" ", "工作流已存在，请勿重复发起");
            return null;
        }

        var lp = Wtm.ServiceProvider.GetRequiredService<IWorkflowLaunchpad>();
        var workflow = await lp.FindStartableWorkflowAsync(workflowDefinitionId, contextId: Entity.GetID().ToString(),
            tenantId: Wtm.LoginUserInfo?.CurrentTenant);
        if (workflow != null)
        {
            var history = new SysWorkflowHistory();
            workflow.WorkflowInstance.Variables.Set("Submitter", Wtm.LoginUserInfo?.ITCode);
            workflow.WorkflowInstance.Variables.Set("SubmitterName", Wtm.LoginUserInfo?.Name);
            workflow.WorkflowInstance.Name = workflowName;
            LoginUserInfo li = new LoginUserInfo
            {
                ITCode = Wtm.LoginUserInfo!.ITCode,
                Name = Wtm.LoginUserInfo.Name,
                UserId = Wtm.LoginUserInfo.UserId,
                PhotoId = Wtm.LoginUserInfo.PhotoId,
                Groups = Wtm.LoginUserInfo.Groups,
                Roles = Wtm.LoginUserInfo.Roles,
                TenantCode = Wtm.LoginUserInfo.CurrentTenant
            };
            var input = new XenApproveInput
            {
                Action = "发起",
                CurrentUser = li
            };
            if (Entity is IBill { GroupId: not null } bill)
            {
                var groupName = bill.Group?.GroupName ?? await DC.Set<SysGroup>()
                    .Where(e => e.ID == bill.GroupId)
                    .Select(e => e.GroupName)
                    .FirstOrDefaultAsync();
                input.GroupId = bill.GroupId;
                input.GroupName = groupName;
                var orgName = bill.Org?.Name ?? await DC.Set<SysOrg>()
                    .Where(e => e.ID == bill.OrgId)
                    .Select(e => e.Name)
                    .FirstOrDefaultAsync();
                workflow.WorkflowInstance.Variables.Set("GroupId", bill.GroupId);
                workflow.WorkflowInstance.Variables.Set("GroupName", groupName);
                workflow.WorkflowInstance.Variables.Set("OrgId", bill.OrgId);
                workflow.WorkflowInstance.Variables.Set("OrgName", orgName);
                workflow.WorkflowInstance.Variables.Set("ModelType", typeof(TModel).FullName);
                workflow.WorkflowInstance.Variables.Set("BillCode", bill.BillCode);
            }

            var rv = await lp.ExecuteStartableWorkflowAsync(workflow, new WorkflowInput
            {
                Input = input
            });
            if (rv.WorkflowInstance?.Faults.Count > 0)
            {
                MSD.AddModelError(" ", rv.WorkflowInstance?.Faults[0].Message);
            }

            history.Approver = li.ITCode;
            history.ApproverName = li.Name;
            history.ApproveGroup = input.GroupName;
            history.ApproverAvatar = Wtm.LoginUserInfo?.PhotoId;
            history.ApproveTime = DateTime.Now;
            history.ApproveResult = "发起";
            history.ActivityId = rv.ActivityId;
            history.WorkflowId = workflow.WorkflowInstance.Id;
            history.WorkflowName = workflowName;
            history.ModelType = typeof(TModel).FullName;
            history.ModelId = Entity.GetID().ToString();
            await DC.Set<SysWorkflowHistory>().AddAsync(history);
            await DC.SaveChangesAsync();
            return rv;
        }

        return null;
    }

    /// <summary>
    /// 继续工作流
    /// </summary>
    /// <param name="actionName"></param>
    /// <param name="remark"></param>
    /// <param name="flowName"></param>
    /// <param name="tag"></param>
    /// <returns></returns>
    public override async Task<RunWorkflowResult> ContinueWorkflowAsync(string actionName, string remark,
        string flowName = null, string tag = null)
    {
        if (Entity is IBill)
        {
            if (Wtm.LoginUserInfo == null || Wtm.LoginUserInfo.Groups.Count == 0)
            {
                MSD.AddModelError(" ", "用户没有分配部门，无法启动工作流");
                return null;
            }
        }

        var scope = Wtm.ServiceProvider.CreateScope();
        var logger = scope.ServiceProvider.GetRequiredService<ILogger<CrudVm<TModel>>>();
        if (!typeof(IWorkflow).IsAssignableFrom(typeof(TModel)))
        {
            logger.LogWarning("执行工作流时，实体类型不支持工作流, {type}", typeof(TModel).FullName);
            MSD.AddModelError(" ", CoreProgram._localizer?["Sys.NoWorkflow"]);
            return null;
        }

        if (!Entity.HasID())
        {
            logger.LogWarning("执行工作流时，实体未保存到数据库, {type}, {@data}", typeof(TModel).FullName, Entity);
            return null;
        }

        try
        {
            var lp = Wtm.ServiceProvider.GetRequiredService<IWorkflowLaunchpad>();
            //不直接使用Wtm.LoginUserInfo，否则elsa会把所有信息序列化保存到WorkflowInstances表中
            LoginUserInfo li = new LoginUserInfo();
            li.ITCode = Wtm.LoginUserInfo.ITCode;
            li.Name = Wtm.LoginUserInfo.Name;
            li.UserId = Wtm.LoginUserInfo.UserId;
            li.PhotoId = Wtm.LoginUserInfo.PhotoId;
            li.Groups = Wtm.LoginUserInfo.Groups;
            li.Roles = Wtm.LoginUserInfo.Roles;
            li.TenantCode = Wtm.LoginUserInfo.CurrentTenant;
            var list = await DC.Set<SysWorkflow>()
                .CheckEqual(flowName, e => e.WorkflowName)
                .WhereIf(string.IsNullOrWhiteSpace(flowName), x => x.ModelType == typeof(TModel).FullName)
                .CheckEqual(tag, e => e.Tag)
                .CheckEqual(Entity.GetID().ToString(), e => e.ModelId)
                .Where(e => e.TenantCode == Wtm.LoginUserInfo.CurrentTenant)
                .ToListAsync();
            foreach (var item in list)
            {
                var duty = string.Empty;
                if (item.Type == SysWorkflowType.用户)
                {
                    if (item.UserCode != Wtm.LoginUserInfo.ITCode) continue;
                }

                if (item.Type == SysWorkflowType.角色)
                {
                    if (Wtm.LoginUserInfo.Roles.All(e => e.ID != item.RoleId)) continue;
                    duty = Wtm.LoginUserInfo.Roles
                        .FirstOrDefault(e => e.ID == item.RoleId)?.RoleName ?? string.Empty;
                }

                if (item.Type == SysWorkflowType.部门)
                {
                    if (Wtm.LoginUserInfo.Groups.All(e => e.ID != item.GroupId)) continue;
                    duty = Wtm.LoginUserInfo.Groups
                        .FirstOrDefault(e => e.ID == item.GroupId)?.GroupName ?? string.Empty;
                }

                if (item.Type == SysWorkflowType.岗位)
                {
                    var jobPositionName = await DC.Set<SysUserJobPosition>()
                        .Where(e => e.UserId == Guid.Parse(Wtm.LoginUserInfo.UserId))
                        .Where(e => e.JobPosition.Roles.Any(x => x.RoleId == item.RoleId))
                        .Where(e => e.JobPosition.Group.ID == item.GroupId)
                        .Select(e => e.JobPosition.Name)
                        .FirstOrDefaultAsync();
                    if (string.IsNullOrWhiteSpace(jobPositionName)) continue;
                    duty = jobPositionName;
                }

                var input = new XenApproveInput
                {
                    Action = actionName,
                    CurrentUser = li,
                    Remark = remark,
                    ApproverDuty = duty
                };
                if (item.GroupId != null)
                {
                    var groupName = DC.Set<SysGroup>()
                        .Where(e => e.ID == item.GroupId)
                        .Select(e => e.GroupName)
                        .FirstOrDefault();
                    input.GroupId = item.GroupId;
                    input.GroupName = groupName;
                }
                else
                {
                    if (Entity is IBill bill)
                    {
                        input.GroupId = bill.GroupId;
                        input.GroupName = bill.Group?.GroupName ?? DC.Set<SysGroup>()
                            .Where(e => e.ID == bill.GroupId)
                            .Select(e => e.GroupName)
                            .FirstOrDefault();
                    }
                }

                var result = await lp.ExecutePendingWorkflowAsync(item.WorkflowId, item.ActivityId, new WorkflowInput
                {
                    Input = input
                });
                if (!result.Executed)
                {
                    // 这里仅记录执行失败的执行记录, 如果成功则在 activity 中记录
                    var history = new SysWorkflowHistory
                    {
                        Approver = li.ITCode,
                        ApproveGroup = input.GroupName,
                        ApproverName = li.Name,
                        ApproverDuty = duty,
                        ApproverAvatar = li.PhotoId,
                        ApproveTime = DateTime.Now,
                        ApproveResult = "异常",
                        ApproveComment = result.Exception?.Message ?? "未知错误",
                        ActivityId = result.ActivityId,
                        WorkflowId = item.WorkflowId,
                        WorkflowName = item.WorkflowName,
                        ModelType = typeof(TModel).FullName,
                        ModelId = Entity.GetID().ToString(),
                        TenantCode = Wtm.LoginUserInfo.CurrentTenant,
                        Tag = tag
                    };
                    logger.LogError(result?.Exception, "执行工作流失败, {@item}", item);
                    var notify = scope.ServiceProvider.GetRequiredService<IWorkflowNotification>();
                    await notify.OnResume(history);
                }

                if (result?.WorkflowInstance?.WorkflowStatus == Elsa.Models.WorkflowStatus.Finished)
                {
                    // 添加完成审批记录
                    var history = new SysWorkflowHistory
                    {
                        ApproveTime = DateTime.Now,
                        ApproveResult = "流程结束",
                        ActivityId = result.ActivityId,
                        WorkflowId = item.WorkflowId,
                        WorkflowName = item.WorkflowName,
                        ModelType = typeof(TModel).FullName,
                        ModelId = Entity.GetID().ToString(),
                        TenantCode = Wtm.LoginUserInfo.CurrentTenant,
                        Tag = tag
                    };
                    var notify = scope.ServiceProvider.GetRequiredService<IWorkflowNotification>();
                    await notify.OnResume(history);
                }

                return result;
            }

            logger.LogWarning("执行工作流时没有找到匹配的工作流, {@actionName}, {@remark}, {@flowName}, {@tag}, {@data}", actionName,
                remark, flowName, tag, Entity);
            MSD.AddModelError(" ", CoreProgram._localizer?["Sys.NoWorkflow"]);
            return null;
        }
        catch (Exception ex)
        {
            MSD.AddModelError(" ", "执行工作流时发生异常: " + ex.Message);
            logger.LogError(ex, "执行工作流时发生异常, {message}. {@data}", ex.Message, new
            {
                actionName,
                remark,
                flowName,
                tag,
                Entity
            });
        }

        return null;
    }


    public async Task<RunWorkflowResult> CancelWorkflowAsync(string reason, string flowName = null, string tag = null)
    {
        if (Entity is IBill bill)
        {
            if (bill.WorkflowStatus == WorkflowStatus.已完成)
            {
                // 如果单据有编号,追加到撤销原因后面
                if (!string.IsNullOrWhiteSpace(bill.BillCode))
                {
                    reason = $"{reason}, 单据编号: {bill.BillCode}";
                }

                bill.WorkflowStatus = WorkflowStatus.已取消;
                // 更新单据状态
                await DC.Set<TModel>()
                    .Where(e => e.ID == Entity.ID)
                    .Cast<IBill>()
                    .ExecuteUpdateAsync(e => e
                        .SetProperty(b => b.WorkflowStatus, WorkflowStatus.已取消));

                // 查询最新的历史记录
                var lastHistory = await DC.Set<SysWorkflowHistory>()
                    .AsNoTracking()
                    .Where(e => e.ModelId == Entity.GetID().ToString())
                    .Where(e => e.TenantCode == Wtm.LoginUserInfo.CurrentTenant)
                    .Where(e => e.ApproveResult == "发起")
                    .OrderByDescending(e => e.ApproveTime)
                    .FirstOrDefaultAsync();

                if (lastHistory == null)
                {
                    MSD.AddModelError(" ", "未找到工作流历史记录");
                    return null;
                }

                // 添加完成审批记录
                var history = new SysWorkflowHistory
                {
                    Approver = Wtm.LoginUserInfo?.ITCode ?? "system",
                    ApproverName = Wtm.LoginUserInfo?.Name ?? "系统管理员",
                    ApproveComment = reason,
                    ApproveTime = DateTime.Now,
                    ApproveResult = "流程撤销",
                    ModelType = typeof(TModel).FullName,
                    ModelId = Entity.GetID().ToString(),
                    TenantCode = Wtm.LoginUserInfo?.CurrentTenant,
                    Tag = tag,
                    ActivityId = lastHistory.ActivityId,
                    WorkflowId = lastHistory.WorkflowId,
                    WorkflowName = lastHistory.WorkflowName
                };
                var scope = Wtm.ServiceProvider.CreateScope();
                var notify = scope.ServiceProvider.GetRequiredService<IWorkflowNotification>();
                await notify.OnResume(history);
            }

            return null;
        }
        else
        {
            MSD.AddModelError(" ", "仅支持工作流单据撤销");
            return null;
        }
    }


    /// <summary>
    /// 获取统计数据
    /// </summary>
    /// <param name="year">年份，如果为空则查询今年数据</param>
    /// <param name="groupId"></param>
    /// <param name="orgId"></param>
    /// <returns></returns>
    public async Task<TotalStatistics> GetStatistics(int? year = null, Guid? groupId = null, Guid? orgId = null)
    {
        // 运行时检查 TModel 是否继承自 BaseBill
        if (typeof(IBill).IsAssignableFrom(typeof(TModel)))
        {
            // 如果年份为空，使用当前年份
            var targetYear = year ?? DateTime.Now.Year;

            // 构建年份范围
            var startDate = new DateTime(targetYear, 1, 1);
            var endDate = new DateTime(targetYear + 1, 1, 1);

            // 如果指定了部门，获取该部门及其所有子部门
            var targetGroupIds = new List<Guid>();
            if (groupId.HasValue)
            {
                targetGroupIds = await GetAllChildrenGroupIds(groupId.Value);
            }

            // 查询数据库，由于有继承关系，可以直接访问 BaseBill 的属性
            var query = DC.Set<TModel>().AsNoTracking();

            // 如果需要强制转换为 BaseBill 来访问特定属性
            var bills = await query.Cast<IBill>()
                .AsNoTracking()
                .CheckEqual(orgId, x => x.OrgId)
                .WhereIf(groupId.HasValue, x => targetGroupIds.Contains(x.GroupId.Value))
                .WhereIf(!groupId.HasValue, x => x.GroupId == null || !groupId.HasValue)
                .Where(x => x.CreateTime >= startDate && x.CreateTime < endDate)
                .ToListAsync();

            // 按月份分组统计 - 仅统计有数据的月份
            var monthlyStatsWithData = bills
                .Where(e => e.CreateTime != null)
                .GroupBy(x => new { x.CreateTime.Value.Year, x.CreateTime.Value.Month })
                .Select(g => new MonthlyStatistics
                {
                    Year = g.Key.Year,
                    Month = g.Key.Month,
                    MonthName = $"{g.Key.Year}年{g.Key.Month}月",
                    // 统计创建的单据数量
                    CreatedCount = g.Count(),
                    // 统计流程中的单据（工作流状态不为空且不是结束状态）
                    InProcessCount = g.Count(x => x.WorkflowStatus == WorkflowStatus.审核中),
                    // 统计流程结束的单据（有审批时间）
                    CompletedCount = g.Count(x => x.WorkflowStatus == WorkflowStatus.已完成),
                    // 统计待处理的单据（工作流状态不为空但没有审批时间）
                    PendingCount = g.Count(x => x.WorkflowStatus == WorkflowStatus.处理中),
                    // 统计待提交状态的单据
                    DraftCount = g.Count(x => x.BillStatus == BillStatus.草稿 && x.WorkflowStatus == WorkflowStatus.待提交)
                })
                .ToDictionary(x => x.Month, x => x);

            // 创建完整的12个月数据
            var monthlyStats = new List<MonthlyStatistics>();
            for (int month = 1; month <= 12; month++)
            {
                if (monthlyStatsWithData.ContainsKey(month))
                {
                    // 使用有数据的统计
                    monthlyStats.Add(monthlyStatsWithData[month]);
                }
                else
                {
                    // 创建空数据的月份统计
                    monthlyStats.Add(new MonthlyStatistics
                    {
                        Year = targetYear,
                        Month = month,
                        MonthName = $"{targetYear}年{month}月",
                        CreatedCount = 0,
                        InProcessCount = 0,
                        CompletedCount = 0,
                        PendingCount = 0,
                        DraftCount = 0
                    });
                }
            }

            // 按部门分组统计
            var departmentStats = new List<DepartmentStatistics>();

            // 获取所有相关部门信息
            var departmentQuery = DC.Set<SysGroup>().AsNoTracking();
            if (groupId.HasValue)
            {
                departmentQuery = departmentQuery.Where(x => targetGroupIds.Contains(x.ID));
            }

            var departments = await departmentQuery.ToListAsync();

            // 为每个部门计算统计数据
            foreach (var dept in departments)
            {
                var deptBills = bills.Where(x => x.GroupId == dept.ID).ToList();

                if (deptBills.Any()) // 只统计有数据的部门
                {
                    // 计算该部门的月度统计
                    var deptMonthlyStatsWithData = deptBills
                        .Where(e => e.CreateTime != null)
                        .GroupBy(x => new { x.CreateTime.Value.Year, x.CreateTime.Value.Month })
                        .Select(g => new MonthlyStatistics
                        {
                            Year = g.Key.Year,
                            Month = g.Key.Month,
                            MonthName = $"{g.Key.Year}年{g.Key.Month}月",
                            CreatedCount = g.Count(),
                            InProcessCount = g.Count(x => x.WorkflowStatus == WorkflowStatus.审核中),
                            CompletedCount = g.Count(x => x.WorkflowStatus == WorkflowStatus.已完成),
                            PendingCount = g.Count(x => x.WorkflowStatus == WorkflowStatus.处理中),
                            DraftCount = g.Count(x =>
                                x.BillStatus == BillStatus.草稿 && x.WorkflowStatus == WorkflowStatus.待提交)
                        })
                        .ToDictionary(x => x.Month, x => x);

                    // 创建该部门完整的12个月数据
                    var deptMonthlyStats = new List<MonthlyStatistics>();
                    for (int month = 1; month <= 12; month++)
                    {
                        if (deptMonthlyStatsWithData.ContainsKey(month))
                        {
                            deptMonthlyStats.Add(deptMonthlyStatsWithData[month]);
                        }
                        else
                        {
                            deptMonthlyStats.Add(new MonthlyStatistics
                            {
                                Year = targetYear,
                                Month = month,
                                MonthName = $"{targetYear}年{month}月",
                                CreatedCount = 0,
                                InProcessCount = 0,
                                CompletedCount = 0,
                                PendingCount = 0,
                                DraftCount = 0
                            });
                        }
                    }

                    departmentStats.Add(new DepartmentStatistics
                    {
                        GroupId = dept.ID,
                        GroupName = dept.GroupName,
                        CreatedCount = deptBills.Count,
                        InProcessCount = deptBills.Count(x => x.WorkflowStatus == WorkflowStatus.审核中),
                        CompletedCount = deptBills.Count(x => x.WorkflowStatus == WorkflowStatus.已完成),
                        PendingCount = deptBills.Count(x => x.WorkflowStatus == WorkflowStatus.处理中),
                        DraftCount = deptBills.Count(x =>
                            x.BillStatus == BillStatus.草稿 && x.WorkflowStatus == WorkflowStatus.待提交),
                        // 新增：包含该部门的月度统计详情
                        MonthlyDetails = deptMonthlyStats.OrderBy(x => x.Month).ToList()
                    });
                }
            }

            // 总体统计
            var totalStats = new TotalStatistics
            {
                // 总创建数量
                TotalCreated = bills.Count,
                // 总流程中数量
                TotalInProcess = bills.Count(x => x.WorkflowStatus == WorkflowStatus.审核中),
                // 总完成数量
                TotalCompleted = bills.Count(x => x.WorkflowStatus == WorkflowStatus.已完成),
                // 总代提交数量
                TotalDraft = bills.Count(x => x.BillStatus == BillStatus.草稿 && x.WorkflowStatus == WorkflowStatus.待提交),
                // 月度统计详情 - 按月份排序
                MonthlyDetails = monthlyStats.OrderBy(x => x.Month).ToList(),
                // 部门统计详情 - 按创建数量排序
                DepartmentDetails = departmentStats.OrderByDescending(x => x.CreatedCount).ToList()
            };

            return totalStats;
        }

        return new TotalStatistics();
    }

    /// <summary>
    /// 获取指定部门及其所有子部门的ID列表
    /// </summary>
    /// <param name="parentGroupId">父部门ID</param>
    /// <returns>包含父部门和所有子部门的ID列表</returns>
    private async Task<List<Guid>> GetAllChildrenGroupIds(Guid parentGroupId)
    {
        var result = new List<Guid> { parentGroupId }; // 包含自身

        // 递归查找所有子部门
        await GetChildrenGroupIdsRecursive(parentGroupId, result);

        return result;
    }

    /// <summary>
    /// 递归获取子部门ID
    /// </summary>
    /// <param name="parentId">父部门ID</param>
    /// <param name="result">结果集合</param>
    private async Task GetChildrenGroupIdsRecursive(Guid parentId, List<Guid> result)
    {
        // 查找直接子部门 - 假设SysGroup有ParentId字段，如果没有则需要根据实际结构调整
        var childGroups = await DC.Set<SysGroup>()
            .AsNoTracking()
            .Where(x => x.ParentId == parentId)
            .Select(x => x.ID)
            .ToListAsync();

        foreach (var childId in childGroups)
        {
            if (!result.Contains(childId))
            {
                result.Add(childId);
                // 递归查找子部门的子部门
                await GetChildrenGroupIdsRecursive(childId, result);
            }
        }
    }
}

/// <summary>
/// 月度统计数据对象
/// </summary>
public class MonthlyStatistics
{
    /// <summary>
    /// 年份
    /// </summary>
    public int Year { get; set; }

    /// <summary>
    /// 月份
    /// </summary>
    public int Month { get; set; }

    /// <summary>
    /// 月份名称
    /// </summary>
    public string MonthName { get; set; }

    /// <summary>
    /// 创建的单据数量
    /// </summary>
    public int CreatedCount { get; set; }

    /// <summary>
    /// 流程中的单据数量
    /// </summary>
    public int InProcessCount { get; set; }

    /// <summary>
    /// 流程结束的单据数量
    /// </summary>
    public int CompletedCount { get; set; }

    /// <summary>
    /// 待处理的单据数量
    /// </summary>
    public int PendingCount { get; set; }

    /// <summary>
    /// 草稿状态的单据数量
    /// </summary>
    public int DraftCount { get; set; }
}

/// <summary>
/// 总体统计数据对象
/// </summary>
public class TotalStatistics
{
    /// <summary>
    /// 总创建数量
    /// </summary>
    public int TotalCreated { get; set; }

    /// <summary>
    /// 总流程中数量
    /// </summary>
    public int TotalInProcess { get; set; }

    /// <summary>
    /// 总完成数量
    /// </summary>
    public int TotalCompleted { get; set; }

    /// <summary>
    /// 总草稿数量
    /// </summary>
    public int TotalDraft { get; set; }

    /// <summary>
    /// 月度统计详情
    /// </summary>
    public List<MonthlyStatistics> MonthlyDetails { get; set; } = new List<MonthlyStatistics>();

    /// <summary>
    /// 部门统计详情
    /// </summary>
    public List<DepartmentStatistics> DepartmentDetails { get; set; } = new List<DepartmentStatistics>();
}

/// <summary>
/// 部门统计数据对象
/// </summary>
public class DepartmentStatistics
{
    /// <summary>
    /// 部门ID
    /// </summary>
    public Guid GroupId { get; set; }

    /// <summary>
    /// 部门名称
    /// </summary>
    public string GroupName { get; set; }

    /// <summary>
    /// 创建的单据数量
    /// </summary>
    public int CreatedCount { get; set; }

    /// <summary>
    /// 流程中的单据数量
    /// </summary>
    public int InProcessCount { get; set; }

    /// <summary>
    /// 流程结束的单据数量
    /// </summary>
    public int CompletedCount { get; set; }

    /// <summary>
    /// 待处理的单据数量
    /// </summary>
    public int PendingCount { get; set; }

    /// <summary>
    /// 草稿状态的单据数量
    /// </summary>
    public int DraftCount { get; set; }

    /// <summary>
    /// 月度统计详情
    /// </summary>
    public List<MonthlyStatistics> MonthlyDetails { get; set; } = new List<MonthlyStatistics>();
}